package com.xinshujia.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinshujia.dao.FunctionDao;
import com.xinshujia.entity.FunctionEntity;
import com.xinshujia.entity.ThresholdEntity;
import com.xinshujia.service.DeviceService;
import com.xinshujia.service.FunctionService;
import com.xinshujia.utils.FunctionConstants;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

/**
 * *************************************
 * *   @author: 野狼上校               **
 * *   @since: 2024-07-18 16:42       **
 * *   @version: 1.0                  **
 * *************************************
 * <p>
 * 与硬件交互的接口实现类
 */
@Service
public class FunctionServiceImpl extends ServiceImpl<FunctionDao, FunctionEntity> implements FunctionService {
    private final FunctionDao functionDao;
    private final DeviceService deviceService;

    public FunctionServiceImpl(FunctionDao functionDao, DeviceService deviceService) {
        this.functionDao = functionDao;
        this.deviceService = deviceService;
    }


    /**
     * (关闭/开启)采集
     * (开启/关闭/清除)报警
     * 查询阈值
     *
     * @param deviceGuid   设备Id
     * @param functionJson 命令 （Json字符串）
     */
    @Override
    public Boolean functionInsert(String deviceGuid, String functionJson) {
        FunctionEntity functionEntity = new FunctionEntity();
        functionEntity.setDeviceGuid(deviceGuid);
        functionEntity.setFunction(functionJson);
        functionEntity.setFunctionResult("");
        functionEntity.setExecuted(0);
        functionEntity.setCreateTime(LocalDateTime.now());
        return functionDao.insert(functionEntity) > 0;
    }

    /**
     * 修改阈值
     *
     * @param deviceGuid   设备Id
     * @param functionJson 命令 （Json字符串）
     * @param threshold    新的阈值
     */
    @Override
    public Boolean functionInsert(String deviceGuid, String functionJson, Double threshold) {
        FunctionEntity functionEntity = new FunctionEntity();
        functionEntity.setDeviceGuid(deviceGuid);
        functionEntity.setFunction(functionJson + threshold + "}");
        functionEntity.setFunctionResult("");
        functionEntity.setExecuted(0);
        functionEntity.setCreateTime(LocalDateTime.now());
        return functionDao.insert(functionEntity) > 0;
    }

    /**
     * 关闭/开启采集
     * </p>
     *
     * @param deviceGuid  设备GUID
     * @param operateType 操作类型 (0: 关闭采集， 1: 开启采集)
     */
    @Override
    public Boolean collectOperate(String deviceGuid, Integer operateType) {
        return switch (operateType) {
            // 关闭采集
            case 0 -> functionInsert(deviceGuid, FunctionConstants.FUNCTION_CLOSE_COLLECT);
            // 开启采集
            case 1 -> functionInsert(deviceGuid, FunctionConstants.FUNCTION_OPEN_COLLECT);
            default -> false;
        };
    }

    /**
     * 关闭/开启/清除报警
     *
     * @param deviceGuid  设备GUID
     * @param operateType 操作类型 (0: 关闭报警， 1: 开启报警, 2: 清除报警)
     */
    @Override
    public Boolean alarmOperate(String deviceGuid, Integer operateType) {
        // 关闭采集
        if (!collectOperate(deviceGuid, 0)) {
            return false;
        }
        // 用于存储最终的操作结果
        Boolean result = false;
        switch (operateType) {
            case 0: // 关闭预警
                // 关闭硬件预警
                result = executeAlarmOperation(deviceGuid,
                        FunctionConstants.FUNCTION_CLOSE_ALARM_X,
                        FunctionConstants.FUNCTION_CLOSE_ALARM_Y,
                        FunctionConstants.FUNCTION_CLOSE_ALARM_Z);
                // 更新设备预警状态
                deviceService.updateDeviceAlarmStatus(deviceGuid, 0);
                break;
            case 1: // 启动预警
                // 开启硬件预警
                result = executeAlarmOperation(deviceGuid,
                        // 替换为实际的启动警报X, Y, Z常量
                        FunctionConstants.FUNCTION_OPEN_ALARM_X,
                        FunctionConstants.FUNCTION_OPEN_ALARM_Y,
                        FunctionConstants.FUNCTION_OPEN_ALARM_Z);
                // 更新设备预警状态
                deviceService.updateDeviceAlarmStatus(deviceGuid, 1);
                break;
            case 2: // 清除警报
                result = functionInsert(deviceGuid, FunctionConstants.FUNCTION_CLEAR_ALARM);
                if (result) {
                    // 开启采集
                    result = collectOperate(deviceGuid, 1);
                }
                break;
            default:
                System.err.println("Unknown operateType: " + operateType);
                break;
        }
        return result;
    }

    /**
     * 修改阈值
     * todo 只能向上修改（上线时再加）
     */
    @Override
    public Boolean updateThreshold(ThresholdEntity thresholdEntity) {
        // 查询当前阈值进行比较
        String deviceGuid = thresholdEntity.getDeviceGuid();
        // 关闭采集
        if (!collectOperate(deviceGuid, 0)) {
            return false;
        }
        // 执行修改阈值
        Boolean flag_x = functionInsert(deviceGuid, FunctionConstants.FUNCTION_UPDATE_THRESHOLD_X, thresholdEntity.getxThreshold());
        Boolean flag_y = functionInsert(deviceGuid, FunctionConstants.FUNCTION_UPDATE_THRESHOLD_Y, thresholdEntity.getyThreshold());
        Boolean flag_z = functionInsert(deviceGuid, FunctionConstants.FUNCTION_UPDATE_THRESHOLD_Z, thresholdEntity.getzThreshold());
        if (flag_x && flag_y && flag_z){
            // 开启采集
            return collectOperate(deviceGuid, 1);
        }
        return false;
    }

    /**
     * 执行预警的具体操作
     *
     * @param deviceGuid    设备GUID
     * @param functionNames 具休的Jason数据
     */
    private Boolean executeAlarmOperation(String deviceGuid, String... functionNames) {
        for (String functionName : functionNames) {
            if (!functionInsert(deviceGuid, functionName)) {
                // 如果任何一个操作失败，则返回false
                return false;
            }
        }
        // 开启采集
        return collectOperate(deviceGuid, 1);
    }

}
